#include "CAN.h"
#include "MyProject.h"
void can_gpio_config(void)
{
  gpio_init_type gpio_init_struct = {0};
	can_base_type can_base_struct = {0};
	can_baudrate_type can_baudrate_struct = {0};
	can_filter_init_type can_filter_init_struct = {0};
	
  crm_periph_clock_enable(CAN_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, FALSE);
	
	can_reset(CAN1);
	crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE);
  /* can base init */
  can_default_para_init(&can_base_struct);
  can_base_struct.mode_selection = CAN_MODE_COMMUNICATE;
  can_base_struct.ttc_enable = FALSE;
  can_base_struct.aebo_enable = TRUE;
  can_base_struct.aed_enable = TRUE;
  can_base_struct.prsf_enable = FALSE;
  can_base_struct.mdrsel_selection = CAN_DISCARDING_LAST_RECEIVED;
  can_base_struct.mmssr_selection = CAN_SENDING_BY_REQUEST;
  can_base_init(CAN1, &can_base_struct);
	
	
	can_baudrate_struct.baudrate_div = 10;
  can_baudrate_struct.rsaw_size = CAN_RSAW_2TQ;
  can_baudrate_struct.bts1_size = CAN_BTS1_7TQ;
  can_baudrate_struct.bts2_size = CAN_BTS2_2TQ;
	can_baudrate_set(CAN1, &can_baudrate_struct);
	
		  /* can filter init */
  can_filter_init_struct.filter_activate_enable = TRUE;
  can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
  can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
  can_filter_init_struct.filter_number = 0;
  can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
  can_filter_init_struct.filter_id_high = 0;
  can_filter_init_struct.filter_id_low = 0;
  can_filter_init_struct.filter_mask_high = 0;
  can_filter_init_struct.filter_mask_low = 0;
  can_filter_init(CAN1, &can_filter_init_struct);
	
  gpio_default_para_init(&gpio_init_struct);
  /* can tx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = CAN_TX;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(CAN_PORT, &gpio_init_struct);
	
	gpio_default_para_init(&gpio_init_struct);
  /* can rx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  gpio_init_struct.gpio_pins = CAN_RX;
  gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  gpio_init(CAN_PORT, &gpio_init_struct);
	
	

  /* can interrupt config */
 // nvic_irq_enable(CAN1_SE_IRQn, 0x00, 0x00);
  nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn, 0x00, 0x01);
  can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);
  //can_interrupt_enable(CAN1, CAN_ETRIEN_INT, TRUE);
  //can_interrupt_enable(CAN1, CAN_EOIEN_INT, TRUE);
}


void can_transmit_data(void)
{
  uint8_t transmit_mailbox;
  can_tx_message_type tx_message_struct;
  tx_message_struct.standard_id = 0x400;
  tx_message_struct.extended_id = 0;
  tx_message_struct.id_type = CAN_ID_STANDARD;
  tx_message_struct.frame_type = CAN_TFT_DATA;
  tx_message_struct.dlc = 8;
  tx_message_struct.data[0] = 0x11;
  tx_message_struct.data[1] = 0x22;
  tx_message_struct.data[2] = 0x33;
  tx_message_struct.data[3] = 0x44;
  tx_message_struct.data[4] = 0x55;
  tx_message_struct.data[5] = 0x66;
  tx_message_struct.data[6] = 0x77;
  tx_message_struct.data[7] = 0x88;
  transmit_mailbox = can_message_transmit(CAN1, &tx_message_struct);
  //while(can_transmit_status_get(CAN1, (can_tx_mailbox_num_type)transmit_mailbox) != CAN_TX_STATUS_SUCCESSFUL);
}
extern float set_Uq;
/**
  *  @brief  can1 interrupt function rx0
  *  @param  none
  *  @retval none
  */
extern uint32_t CAN_timeout;
extern uint8_t zero_set_in_st;
extern uint8_t start_flag;
void USBFS_L_CAN1_RX0_IRQHandler (void)
{
  can_rx_message_type rx_message_struct;
  if(can_interrupt_flag_get(CAN1,CAN_RF0MN_FLAG) != RESET)
  {
    can_message_receive(CAN1, CAN_RX_FIFO0, &rx_message_struct);
#if MODE
    if(rx_message_struct.standard_id == 0x400)
		{
			CAN_timeout = 0;
			#if (LUN_NUM == 1)
			 set_Uq = (float)(rx_message_struct.data[1] | (uint16_t)rx_message_struct.data[2] <<8 ) / 1000.0f;
			 if(rx_message_struct.data[0] & 0x01)
			#else
			 set_Uq = (float)(rx_message_struct.data[3] | (uint16_t)rx_message_struct.data[4] <<8 ) / 1000.0f;
			 if(rx_message_struct.data[0] & 0x02)
			#endif
			 {
					set_Uq = - set_Uq;
			 }
		 }
#else
			#if (GUANJIE_NUM == 1)
			if(rx_message_struct.standard_id == 0x685)
			{
				if(rx_message_struct.data[5] == 'Y')
				{
					start_flag = 1;
				}
			}
			if(rx_message_struct.standard_id == 0x401)
			{
				 CAN_timeout = 0;
				 if(rx_message_struct.data[5] & 0x01)
				 {
						zero_set_in_st = 1;
				 }
			 set_Uq = (float)(rx_message_struct.data[1] | (uint16_t)rx_message_struct.data[2] <<8 ) / 1000.0f;
			 if(rx_message_struct.data[0] & 0x01)
			#elif (GUANJIE_NUM == 2)
			if(rx_message_struct.standard_id == 0x682)
			{
				if(rx_message_struct.data[5] == 'Y')
				{
					start_flag = 1;
				}
			}
			if(rx_message_struct.standard_id == 0x682)
			{
				if(rx_message_struct.data[3] == 'S')
				{
					zero_set_in_st = 1;
				}
			}
			if(rx_message_struct.standard_id == 0x401)
			{
			 CAN_timeout = 0;
			 set_Uq = (float)(rx_message_struct.data[3] | (uint16_t)rx_message_struct.data[4] <<8 ) / 1000.0f;
			 if(rx_message_struct.data[0] & 0x02)
			#elif (GUANJIE_NUM == 3)
			if(rx_message_struct.standard_id == 0x682)
			{
				if(rx_message_struct.data[5] == 'Y')
				{
					start_flag = 1;
				}
			}
			if(rx_message_struct.standard_id == 0x683)
			{
				if(rx_message_struct.data[3] == 'S')
				{
					zero_set_in_st = 1;
				}
			}
			if(rx_message_struct.standard_id == 0x402)
			{
			 CAN_timeout = 0;
			 set_Uq = (float)(rx_message_struct.data[1] | (uint16_t)rx_message_struct.data[2] <<8 ) / 1000.0f;
			 if(rx_message_struct.data[0] & 0x01)
			#elif (GUANJIE_NUM == 4)
			if(rx_message_struct.standard_id == 0x682)
			{
				if(rx_message_struct.data[5] == 'Y')
				{
					start_flag = 1;
				}
			}
			if(rx_message_struct.standard_id == 0x684)
			{
				if(rx_message_struct.data[3] == 'S')
				{
					zero_set_in_st = 1;
				}
			}
			if(rx_message_struct.standard_id == 0x402)
			{
			 CAN_timeout = 0;
			 set_Uq = (float)(rx_message_struct.data[3] | (uint16_t)rx_message_struct.data[4] <<8 ) / 1000.0f;
			 if(rx_message_struct.data[0] & 0x02)
			 #else
			{
			#endif
			 {
					set_Uq = - set_Uq;
			 }
			}
#endif
		LED_toggle();
		}
}

void CAN1_SE_IRQHandler(void)
{
  __IO uint32_t err_index = 0;
  if(can_interrupt_flag_get(CAN1,CAN_ETR_FLAG) != RESET)
  {
    err_index = CAN1->ests & 0x70;
    can_flag_clear(CAN1, CAN_ETR_FLAG);
    /* error type is stuff error */
    if(err_index == 0x00000010)
    {
      /* when stuff error occur: in order to ensure communication normally,
      user must restart can or send a frame of highest priority message here */
    }
  }
}